Subsets II

Time: O(Nx2^N); Space: O(1); medium

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Notes:

  • Each element in a subset must be in non-descending order.

  • The ordering between two subsets is free.

  • The solution set must not contain duplicate subsets.

Example 1:

Input: [1,2,2]

Output:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

Example 2:

Input: [0]

Output:

[
  [],
  [0]
]
[1]:
class Solution1(object):
    """
    Time: O(N*2^N)
    Space: O(1)
    """
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        result = [[]]
        previous_size = 0
        for i in range(len(nums)):
            size = len(result)
            for j in range(size):
                # Only union non-duplicate element or new union set.
                if i == 0 or nums[i] != nums[i - 1] or j >= previous_size:
                    result.append(list(result[j]))
                    result[-1].append(nums[i])
            previous_size = size
        return result
[2]:
s = Solution1()

nums = [1,2,3]
# print(s.subsetsWithDup(nums))
assert s.subsetsWithDup(nums) ==  [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

nums = [0]
assert s.subsetsWithDup(nums) ==  [[],[0]] or [[0],[]]
[3]:
class Solution2(object):
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []
        i, count = 0, 1 << len(nums)
        nums.sort()

        while i < count:
            cur = []
            for j in range(len(nums)):
                if i & 1 << j:
                    cur.append(nums[j])
            if cur not in result:
                result.append(cur)
            i += 1

        return result
[4]:
s = Solution2()

nums = [1,2,3]
# print(s.subsetsWithDup(nums))
assert s.subsetsWithDup(nums) ==  [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

nums = [0]
assert s.subsetsWithDup(nums) ==  [[],[0]] or [[0],[]]
[5]:
class Solution3(object):
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []
        self.subsetsWithDupRecu(result, [], sorted(nums))
        return result

    def subsetsWithDupRecu(self, result, cur, nums):
        if not nums:
            if cur not in result:
                result.append(cur)
        else:
            self.subsetsWithDupRecu(result, cur, nums[1:])
            self.subsetsWithDupRecu(result, cur + [nums[0]], nums[1:])
[9]:
s = Solution3()

nums = [1,2,3]
# print(s.subsetsWithDup(nums))
assert s.subsetsWithDup(nums) ==  [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]

nums = [0]
assert s.subsetsWithDup(nums) ==  [[],[0]] or [[0],[]]